using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using ITSP.SharePoint.CacheRefresh.Common;
using Microsoft.Practices.SharePoint.Common.Logging;
using Microsoft.Practices.SharePoint.Common.ServiceLocation;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Security;

namespace ITSP.SharePoint.CacheRefresh.Features.CacheConfiguration
{
    /// <summary>
    /// This feature receiver creates the cache configuration list at the root of the web application.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>
    [Guid("e7be3e47-283c-4b0e-ab87-83c86b98bb33")]
    public class CacheConfigurationEventReceiver : SPFeatureReceiver
    {
        private readonly ILogger _logger = SharePointServiceLocator.GetCurrent().GetInstance<ILogger>();

        /// <summary>
        /// Create the Cache Configuration List for the Web Application
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            // get the hub sitecollection from the mms
            _logger.TraceToDeveloper("CacheConfigurationEventReceiver::FeatureActivated() Enter", 0, TraceSeverity.Verbose, Constants.Logging.DefaultLoggingCategory);

            SPWebApplication webApplication = properties.Feature.Parent as SPWebApplication;

            SPSite rootSite = webApplication.Sites.FirstOrDefault();
            if(rootSite==null)
            {
                throw new SPException("Please create a root site collection in the selected web application");
            }

            SPSecurity.RunWithElevatedPrivileges(delegate 
            {
                using (SPSite site = new SPSite(rootSite.ID))
                {
                    site.CatchAccessDeniedException = false;
                    List<Guid> activateFeatures=new List<Guid>(){new Guid(Constants.Lists.CacheListFeatureId), new Guid(Constants.Features.CacheListSettingsFeatureId)};

                    foreach (var activateFeature in activateFeatures)
                    {
                        SPFeatureDefinition featureDefinition = SPFarm.Local.FeatureDefinitions.FirstOrDefault(fd => fd.Id == activateFeature);
                        SPFeature checkFeature = null;
                        switch (featureDefinition.Scope)
                        {
                            case SPFeatureScope.Web:
                                checkFeature = site.RootWeb.Features.FirstOrDefault(f => f.DefinitionId == featureDefinition.Id);
                                break;
                            case SPFeatureScope.Site:
                                checkFeature = site.Features.FirstOrDefault(f => f.DefinitionId == featureDefinition.Id);
                                break;
                            default:
                                break;
                        }
                        
                        if (checkFeature == null)
                        {
                            _logger.TraceToDeveloper(String.Format("Activating Cache Configuration Sub Features {0} on {1}", featureDefinition.DisplayName, rootSite), 0, TraceSeverity.Verbose, Constants.Logging.DefaultLoggingCategory);

                            switch (featureDefinition.Scope)
                            {
                                case SPFeatureScope.Web:
                                site.RootWeb.Features.Add(activateFeature);
                                break;
                                    case SPFeatureScope.Site:
                                    site.Features.Add(activateFeature);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
               
                }
            });
            

            _logger.TraceToDeveloper("CacheConfigurationEventReceiver::FeatureActivated() Exit", 0, TraceSeverity.Verbose, Constants.Logging.DefaultLoggingCategory);
        }


        // Uncomment the method below to handle the event raised before a feature is deactivated.

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            // get the hub sitecollection from the mms
            _logger.TraceToDeveloper("CacheConfigurationEventReceiver::FeatureActivated() Enter", 0, TraceSeverity.Verbose, Constants.Logging.DefaultLoggingCategory);

            SPWebApplication webApplication = properties.Feature.Parent as SPWebApplication;

            SPSite rootSite = webApplication.Sites.FirstOrDefault();
            if (rootSite == null)
            {
                throw new SPException("Please create a root site collection in the selected web application");
            }

            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                using (SPSite site = new SPSite(rootSite.ID))
                {
                    site.CatchAccessDeniedException = false;
                    List<Guid> deActivateFeatures = new List<Guid>() { new Guid(Constants.Features.CacheListSettingsFeatureId) };

                    foreach (var deActivateFeature in deActivateFeatures)
                    {
                        SPFeatureDefinition featureDefinition = SPFarm.Local.FeatureDefinitions.FirstOrDefault(fd => fd.Id == deActivateFeature);
                        SPFeature checkFeature = null;
                        switch (featureDefinition.Scope)
                        {
                            case SPFeatureScope.Web:
                                checkFeature = site.RootWeb.Features.FirstOrDefault(f => f.DefinitionId == featureDefinition.Id);
                                break;
                            case SPFeatureScope.Site:
                                checkFeature = site.Features.FirstOrDefault(f => f.DefinitionId == featureDefinition.Id);
                                break;
                            default:
                                break;
                        }

                        if (checkFeature != null)
                        {
                            _logger.TraceToDeveloper(String.Format("Deactivating Cache Configuration Sub Features {0} on {1}", featureDefinition.DisplayName, rootSite), 0, TraceSeverity.Verbose, Constants.Logging.DefaultLoggingCategory);

                            switch (featureDefinition.Scope)
                            {
                                case SPFeatureScope.Web:
                                    site.RootWeb.Features.Remove(deActivateFeature);
                                    break;
                                case SPFeatureScope.Site:
                                    site.Features.Remove(deActivateFeature);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }

                }
            });


            _logger.TraceToDeveloper("CacheConfigurationEventReceiver::FeatureActivated() Exit", 0, TraceSeverity.Verbose, Constants.Logging.DefaultLoggingCategory);
        }


        // Uncomment the method below to handle the event raised after a feature has been installed.

        //public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        //{
        //}


        // Uncomment the method below to handle the event raised before a feature is uninstalled.

        //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        //{
        //}

        // Uncomment the method below to handle the event raised when a feature is upgrading.

        //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        //{
        //}
    }
}
